package fr.sedoo.metadata.client.ui.widget.dialog.contact;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DefaultLocalizedNames;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

import fr.sedoo.commons.client.message.CommonMessages;
import fr.sedoo.commons.client.util.ElementUtil;
import fr.sedoo.commons.client.util.ListUtil;
import fr.sedoo.commons.client.util.StringUtil;
import fr.sedoo.commons.client.widget.ConfirmCallBack;
import fr.sedoo.commons.client.widget.DialogBoxTools;
import fr.sedoo.commons.client.widget.dialog.OkCancelContent;
import fr.sedoo.commons.client.widget.editing.ValidationAlert;
import fr.sedoo.metadata.client.ui.widget.common.RolePanel;
import fr.sedoo.metadata.shared.domain.dto.PersonDTO;

public abstract class PersonDialogBoxContent extends Composite implements OkCancelContent, PersonDTOEditor {

	private static PersonDialogBoxContentUiBinder uiBinder = GWT.create(PersonDialogBoxContentUiBinder.class);

	interface PersonDialogBoxContentUiBinder extends UiBinder<Widget, PersonDialogBoxContent> {
	}

	@UiField
	TextBox personName;

	@UiField
	TextBox email;

	@UiField
	TextBox organisationName;

	@UiField
	TextBox street;

	@UiField
	TextBox city;

	@UiField
	TextBox zipcode;

	@UiField(provided = true)
	ListBox countries;

	@UiField(provided = true)
	RolePanel rolePanel;

	@UiField
	Label roleLabel;

	private static final String SINGLE_ROLE_HEIGHT = "300px";

	private static final String MULTIPLE_ROLE_HEIGHT = "550px";

	private String preferredHeight;

	private DialogBox dialog;

	private ConfirmCallBack confirmCallBack;

	private List<String> roles;

	private static List<String> countryNames;

	public PersonDialogBoxContent(List<String> roles) {
		this.roles = roles;
		countries = new ListBox();
		countries.addItem("");
		initCountryNames();
		Iterator<String> iterator = countryNames.iterator();
		while (iterator.hasNext()) {
			countries.addItem(iterator.next());
		}
		rolePanel = new RolePanel(roles);
		initWidget(uiBinder.createAndBindUi(this));
		if (roles.size() == 1) {
			hideRolePanel();
			preferredHeight = SINGLE_ROLE_HEIGHT;
		} else {
			preferredHeight = MULTIPLE_ROLE_HEIGHT;
		}
	}

	private void initCountryNames() {
		if (countryNames == null) {
			countryNames = new ArrayList<String>();
			DefaultLocalizedNames cNames = new DefaultLocalizedNames();
			for (String countryCode : cNames.getSortedRegionCodes()) {
				countryNames.add(cNames.getRegionName(countryCode));
			}
		}
	}

	private void hideRolePanel() {
		ElementUtil.hide(rolePanel);
		ElementUtil.hide(roleLabel);
	}

	public void setConfirmCallBack(ConfirmCallBack confirmCallBack) {
		this.confirmCallBack = confirmCallBack;
	}

	private PersonDTO flush() {
		PersonDTO aux = createDTO();
		aux.setEmail(StringUtil.trimToEmpty(email.getText()));
		aux.setOrganisationName(StringUtil.trimToEmpty(organisationName.getText()));
		aux.setPersonName(StringUtil.trimToEmpty(personName.getText()));
		aux.setAddress(StringUtil.trimToEmpty(street.getText()));
		aux.setCountry(StringUtil.trimToEmpty(countries.getValue(countries.getSelectedIndex())));
		aux.setCity(StringUtil.trimToEmpty(city.getText()));
		aux.setZipCode(StringUtil.trimToEmpty(zipcode.getText()));

		if (roles.size() == ListUtil.SINGLETON_SIZE) {
			aux.setRoles(roles.get(ListUtil.FIRST_INDEX));
		} else {
			aux.setRoles(rolePanel.flush());
		}

		return aux;
	}

	public abstract PersonDTO createDTO();

	public void setDialogBox(DialogBox dialog) {
		this.dialog = dialog;
	}

	public void edit(PersonDTO item) {
		if (item != null) {
			email.setText(StringUtil.trimToEmpty(item.getEmail()));
			organisationName.setText(StringUtil.trimToEmpty(item.getOrganisationName()));
			personName.setText(StringUtil.trimToEmpty(item.getPersonName()));
			rolePanel.edit(StringUtil.trimToEmpty(item.getRoles()));
			street.setText(StringUtil.trimToEmpty(item.getAddress()));
			selectCountry(item.getCountry());
			zipcode.setText(StringUtil.trimToEmpty(item.getZipCode()));
			city.setText(StringUtil.trimToEmpty(item.getCity()));
		}
	}

	private void selectCountry(String country) {
		String aux = StringUtil.trimToEmpty(country);
		int itemCount = countries.getItemCount();
		for (int i = 0; i < itemCount; i++) {
			if (countries.getItemText(i).compareToIgnoreCase(aux) == 0) {
				countries.setItemSelected(i, true);
				return;
			}
		}
		countries.setItemSelected(0, true);
	}

	@Override
	public PersonDTO getValue() {
		return flush();
	}

	@Override
	public String getPreferredHeight() {
		return preferredHeight;
	}

	@Override
	public void okClicked() {
		PersonDTO aux = flush();
		List<ValidationAlert> result = aux.validate();
		if (result.isEmpty()) {
			if (dialog != null) {
				dialog.hide();
				confirmCallBack.confirm(true);
			}
		} else {
			DialogBoxTools.popUpScrollable(CommonMessages.INSTANCE.error(), ValidationAlert.toHTML(result), DialogBoxTools.HTML_MODE);
		}

	}

	@Override
	public void cancelClicked() {
		if (dialog != null) {
			dialog.hide();
		}

	}

}
